package com.simon.study.algorithm.thread;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Semaphore;

/**
 * <p>
 *
 * @author SimonLiu
 * @date 2022/8/29 22:00
 */
public class ThreadUtil {
    public static int[] data = new int[10];

    public static void countDownLatchUse() throws Exception{
        CountDownLatch latch = new CountDownLatch(10);

        for (int i = 0; i < 10; i++) {
            final int temp = i;

            new Thread( () -> {
                Random random = new Random();
                data[temp] = random.nextInt(10001);

                latch.countDown();
            }).start();
        }

        latch.await();
        System.out.println("min: " + Arrays.stream(data).min() );
    }


    public static void cyclicBarrierUse(){
        CyclicBarrier barrier = new CyclicBarrier(5);

        for (int i = 0; i < 5; i++) {
            new Thread( () -> {
                long start = System.currentTimeMillis();
                try {
                    System.out.println(Thread.currentThread().getName() + " at run");
                    Random random = new Random();
                    int b = 100 + 100 * (random.nextInt(5) + 1);

                    System.out.println("start sleep: " + b + " ms.");
                    Thread.sleep(b);
                    System.out.println("start barrier await");
                    barrier.await();
                }catch (InterruptedException e){
                    e.printStackTrace();
                }catch (BrokenBarrierException e){
                    e.printStackTrace();
                }
                System.out.println( "Costs " + (System.currentTimeMillis()-start) + "ms." );
            }).start();
        }
    }


    public static void semaphoreUse(){
        Semaphore semaphore = new Semaphore(5);

        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName() + " start.");

                try {
                    System.out.println(Thread.currentThread().getName() + " start semaphoring.");
                    semaphore.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(Thread.currentThread().getName() + " in semaphore area.");
                try {
                    Thread.sleep(350);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " begin to leave semaphore area.");
                semaphore.release();

                System.out.println(Thread.currentThread().getName() + " out of semaphore area.");
            }).start();
        }
    }
}
